/*
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * openFuyao is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

// Package utils 存放辅助方法
package utils

import (
	"fmt"
	"os"
	"os/user"
	"path/filepath"
	"strings"
)

const commonPathBeginIdx = 2 // 包含家目录时正常路径开始索引

// PathExpander 路径展开器
type PathExpander struct {
	// 是否展开通配符
	ExpandWildcards bool
	// 是否展开环境变量
	ExpandEnvVars bool
}

// NewPathExpander 创建新的路径展开器
func NewPathExpander() *PathExpander {
	return &PathExpander{
		ExpandWildcards: true,
		ExpandEnvVars:   true,
	}
}

// ExpandPaths 展开文件路径列表
func (p *PathExpander) ExpandPaths(paths []string) ([]string, error) {
	var result []string

	for _, path := range paths {
		expanded, err := p.ExpandPath(path)
		if err != nil {
			return nil, err
		}
		result = append(result, expanded...)
	}

	return result, nil
}

// ExpandPath 展开单个文件路径
func (p *PathExpander) ExpandPath(path string) ([]string, error) {
	var result []string

	// 展开环境变量
	if p.ExpandEnvVars {
		path = p.expandEnvironmentVariables(path)
	}

	// 检查路径是否包含通配符
	if p.ExpandWildcards && containsWildcard(path) {
		matches, err := filepath.Glob(path)
		if err != nil {
			return nil, fmt.Errorf("expand wildcard failed: %v", err)
		}

		for _, match := range matches {
			result = append(result, match)
		}
	} else {
		// 没有通配符，直接添加
		result = append(result, path)
	}

	return result, nil
}

// expandEnvironmentVariables 展开环境变量
func (p *PathExpander) expandEnvironmentVariables(path string) string {
	// 展开标准环境变量
	path = os.ExpandEnv(path)

	// 特殊处理 ~ (家目录)
	if strings.HasPrefix(path, "~") {
		if usr, err := user.Current(); err == nil {
			homeDir := usr.HomeDir
			if path == "~" {
				path = homeDir
			} else if strings.HasPrefix(path, "~/") {
				path = filepath.Join(homeDir, path[commonPathBeginIdx:])
			} else {
				return path
			}
		}
	}

	return path
}

// containsWildcard 检查路径是否包含通配符
func containsWildcard(path string) bool {
	wildcards := []string{"*", "?", "[", "]"}
	for _, wc := range wildcards {
		if strings.Contains(path, wc) {
			return true
		}
	}
	return false
}
